package main

import (
	"fmt"
	"vov.cx/kagura/utils/app"
	"vov.cx/kagura/utils/exec"
)

func init() {
	//upx
	root.AddCommand(app.New(
		app.Use("pack [flags] <files...>", "upx"),
		app.Comment("upx wrapper"),
		app.Flags(setUPX),
		app.Run(func(c *app.Command, files []string) {
			if len(files) == 0 {
				_ = c.Help()
			}
			app.CheckExit(getUPX(c.Flags(), files).Run(c.Context()))
		}),
	))
}

func setUPX(fs *app.FlagSet) {
	fs.BoolP("decompress", "d", false, "decompress")
	fs.StringP("output", "o", "", "write output to 'FILE'")
	fs.BoolP("quiet", "q", false, "be quiet")
	fs.BoolP("backup", "k", false, "keep backup files")
	fs.String("overlay", "", `copy: copy any extra data attached to the file [default]
strip: strip any extra data attached to the file [DANGEROUS]
skip: don't compress a file with an overlay
`)
	fs.IntP("level", "c", 0, "compress level")
	fs.BoolP("fast", "1", false, "compress faster")
	fs.BoolP("better", "9", false, "compress better")
	fs.Bool("best", false, "compress best (can be slow for big files)")
	fs.BoolP("brute", "b", false, "try all available compression methods & filters [slow]")
	fs.BoolP("ultra-brute", "u", false, "try even more compression variants [very slow]")

	fs.BoolP("list", "l", false, "list compressed file")
}

func getUPX(fs *app.FlagSet, files []string) *exec.Command {
	var args []string

	if decompress, _ := fs.GetBool("decompress"); decompress {
		args = append(args, "-d")
	}

	quiet, _ := fs.GetBool("quiet")
	if quiet {
		args = append(args, "-q", "--no-color", "--mono", "--color", "--no-progress")
	}

	if backup, _ := fs.GetBool("backup"); backup {
		args = append(args, "--backup")
	}

	if overlay, _ := fs.GetString("overlay"); overlay != "" {
		args = append(args, fmt.Sprintf("--overlay=%s", overlay))
	}

	if level, _ := fs.GetInt("level"); level >= 1 && level <= 11 {
		if level <= 9 {
		} else {
			switch level {
			case 10:
				args = append(args, "--brute")
			case 11:
				args = append(args, "--ultra-brute")
			default:
				args = append(args, fmt.Sprintf("-%d", level))
			}
		}
	} else {
		if ultraBrute, _ := fs.GetBool("ultra-brute"); ultraBrute {
			args = append(args, "--ultra-brute")
		} else if brute, _ := fs.GetBool("brute"); brute {
			args = append(args, "--brute")
		} else if best, _ := fs.GetBool("best"); best {
			args = append(args, "--best")
		} else if better, _ := fs.GetBool("better"); better {
			args = append(args, "-9")
		} else if fast, _ := fs.GetBool("fast"); fast {
			args = append(args, "-1")
		}
	}

	if list, _ := fs.GetBool("list"); list {
		args = append(args, "-l")
	}

	args = append(args, files...)

	cmd := exec.New("upx", args...)
	if quiet {
		return cmd.NoStdOut()
	}
	return cmd
}
